﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Net.NetworkInformation;
using System.Collections;

namespace ChatServer
{
    class Program
    {
        static List<Client> list = new List<Client>();   //存储链接的所有客户端
        static void Main(string[] args)
        {
            //建立Socket
            Socket tcpSever = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定IP
            //tcpSever.Bind(new IPEndPoint(IPAddress.Parse("192.168.3.238"), 1001));
            ADDEWSSFAM IPv4 = new ADDEWSSFAM();
            string ipv4 = GetIP(IPv4);
            //Console.WriteLine(ipv4);
            int port = GetFirstAvailablePort();
            Console.WriteLine("端口号:" + port);
            Console.Write("是否更换端口(是1  否2):");
            int index = int.Parse(Console.ReadLine());
            if (index == 1)
            {
                Console.Write("请输入端口号:");
                port = int.Parse(Console.ReadLine());
                Console.WriteLine("端口号:" + port);
            }
            //tcpSever.Bind(new IPEndPoint(IPAddress.Parse(ipv4), 1001));
            tcpSever.Bind(new IPEndPoint(IPAddress.Parse(ipv4), port));

            //监听
            tcpSever.Listen(100);
            Console.WriteLine("服务器已开启");
            while (true)
            {
                Socket socketClient = tcpSever.Accept();   //等待接收
                Client client = new Client(socketClient);
                list.Add(client);
            }
        }

        public static void BroadcastMessage(string message)   //分发消息
        {
            List<Client> notConnect = new List<Client>();
            foreach (Client item in list)
            {
                if (item.IsConnected)
                {
                    item.SendMessages(message);
                }
                else
                {
                    notConnect.Add(item);
                }
            }
            foreach (var item in notConnect)
            {
                list.Remove(item);
            }
            notConnect.Clear();
        }

        public enum ADDEWSSFAM
        {
            IPv4, IPv6
        }

        public static string GetIP(ADDEWSSFAM addfam)
        {
            if (addfam == ADDEWSSFAM.IPv6 && !Socket.OSSupportsIPv6)
            {
                return null;
            }

            string output = "";

            foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
            {
                NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
                NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
                if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2))
                {
                    foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            output = ip.Address.ToString();
                        }
                    }
                }
            }

            return output;
        }

        /// <summary>
        /// 获取第一个可用的端口号
        /// </summary>
        /// <returns></returns>
        public static int GetFirstAvailablePort()
        {
            int MAX_PORT = 6000; //系统tcp/udp端口数最大是65535           
            int BEGIN_PORT = 5000;//从这个端口开始检测

            for (int i = BEGIN_PORT; i < MAX_PORT; i++)
            {
                if (PortIsAvailable(i)) return i;
            }
            return -1;
        }

        /// <summary>
        /// 获取操作系统已用的端口号
        /// </summary>
        /// <returns></returns>
        public static IList PortIsUsed()
        {
            //获取本地计算机的网络连接和通信统计数据的信息
            IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();

            //返回本地计算机上的所有Tcp监听程序
            IPEndPoint[] ipsTCP = ipGlobalProperties.GetActiveTcpListeners();

            //返回本地计算机上的所有UDP监听程序
            IPEndPoint[] ipsUDP = ipGlobalProperties.GetActiveUdpListeners();

            //返回本地计算机上的Internet协议版本4(IPV4 传输控制协议(TCP)连接的信息。
            TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
            IList allPorts = new ArrayList();
            foreach (IPEndPoint ep in ipsTCP) allPorts.Add(ep.Port);
            foreach (IPEndPoint ep in ipsUDP) allPorts.Add(ep.Port);
            foreach (TcpConnectionInformation conn in tcpConnInfoArray) allPorts.Add(conn.LocalEndPoint.Port);
            return allPorts;
        }

        /// <summary>
        /// 检查指定端口是否已用
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public static bool PortIsAvailable(int port)
        {
            bool isAvailable = true;
            IList portUsed = PortIsUsed();
            foreach (int p in portUsed)
            {
                if (p == port)
                {
                    isAvailable = false; break;
                }
            }
            return isAvailable;
        }
    }
}
